package com.javajun.service;

import java.util.HashSet;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.javajun.custom.BaseService;
import com.javajun.entity.StuNum;
import com.javajun.entity.Student;
import com.javajun.form.StudentForm;
import com.javajun.repository.StudentRepository;

@Service
public class StudentServcie extends BaseService<Student, Integer>{

    @Autowired
    private StudentRepository studentRepository;
    
    @Autowired
    private StuNumService stuNumService;
    
    @Autowired
    private SysRoleService sysRoleService;
    
    @Autowired
    private SysUserService sysUserService;
    
    private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    /**
     * 通过email查找一个学生
     * @param email
     * @return
     */
    public Student findByEmail(String email) {
        // TODO Auto-generated method stub
        return studentRepository.findByEmail(email);
    }
    
    /**
     * 通过表单保存一个学生
     * @param form
     * @return
     */
    public void save(StudentForm form) {
        Student entity = new Student();
        Integer id = form.getId();
        if(id != null) {
           entity = findById(id);
        } else {
            entity.getSysRole().add(sysRoleService.getStudentRole());
            entity.setPassword(encoder.encode("1111"));
            // 设置学号
            // 判断该邮箱是否已存在，不存在则生成学号~
            if(sysUserService.findByEmail(form.getEmail()) == null) {
                StuNum stuNum = genStuNumEntity();
                stuNumService.save(stuNum);
                stuNum = stuNumService.findByStuNum(stuNum.getStuNum());
                entity.setStuNum(stuNum);
                entity.setUsername(stuNum.getStuNum());
            }
        }
        
        String name = form.getName();
        entity.setName(name);
        String email = form.getEmail();
        entity.setEmail(email);
        String phone = form.getPhone();
        entity.setPhone(phone);
        save(entity);
    }
    
    /**
     * 生成一个学号，字符串
     * @return
     */
    public String genStuNumStr() {
        List<StuNum> stuNums = stuNumService.findAllByOrderByIdDesc();
        Integer stuNumInt = 0;
        if(stuNums.size() > 0) {
            StuNum stuNum = stuNums.get(0);
            if(stuNum != null) {
                try {
                    stuNumInt = Integer.parseInt(stuNum.getStuNum());
                } catch (NumberFormatException e) {
                    stuNumInt = 0; 
                }
            }
        }
        stuNumInt++;
        String stuNumStr = String.format("%04d", stuNumInt);
        return stuNumStr;
    }
    
    /**
     * 生成一个新的学学号对象
     * @return
     */
    public StuNum genStuNumEntity() {
        return new StuNum(genStuNumStr());
    }

    /**
     * 学生的安全查询
     * @param form
     * @return
     */
    public Specification<Student> buildSpec(StudentForm form) {
        Specification<Student> specification = new Specification<Student>() {

            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            @Override
            public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                HashSet<Predicate> rules=new HashSet<>();
                String username = form.getUsername();
                if(StringUtils.hasText(username)) {
                    rules.add(cb.like(root.get("username"), "%"+username+"%"));
                }
                String email = form.getEmail();
                if(StringUtils.hasText(email)) {
                    rules.add(cb.like(root.get("email"), "%"+email+"%"));
                }
                String phone = form.getPhone();
                if(StringUtils.hasText(phone)) {
                    rules.add(cb.like(root.get("phone"), "%"+phone+"%"));
                }
                String name = form.getName();
                if(StringUtils.hasText(name)) {
                    rules.add(cb.like(root.get("name"), "%"+name+"%"));
                }
                return cb.and(rules.toArray(new Predicate[rules.size()]));
            }
        };
        return specification;
    }
    
}
